package com.basics.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.basics.api.enums.channel.ChannelTypeEnum;
import com.basics.api.enums.socket.MessageEnum;
import com.basics.api.request.channel.*;
import com.basics.api.response.channel.ChannelPostListData;
import com.basics.api.response.channel.CommentData;
import com.basics.api.response.channel.PostCommentListData;
import com.basics.api.response.channel.PostInfoData;
import com.basics.api.service.PostApiService;
import com.basics.channel.entity.*;
import com.basics.common.exception.CustomException;
import com.basics.common.utils.AsyncUtil;
import com.basics.common.utils.StringUtils;
import com.basics.organization.entity.CyOrganization;
import com.basics.post.entity.CyChannelPost;
import com.basics.post.entity.CyChannelPostFile;
import com.basics.post.entity.CyChannelPostPrise;
import com.basics.post.entity.CyChannelPostUser;
import com.basics.user.entity.CyUser;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


@Service
public class PostApiServiceImpl extends BaseApiService implements PostApiService {



    @Override
    public IPage<ChannelPostListData> selectChannelPostList(ChannelPostReq req, Long userId){
        IPage<ChannelPostListData> page = cyChannelPostService.selectChannelPostList(new Page(req.getPageNum(),req.getPageSize())
                ,req.getChannelId(),userId,req.getTopicId());
        if(CollectionUtils.isNotEmpty(page.getRecords())){
            CyOrganization cyOrganization = cyOrganizationService.getById(req.getOrganizationId());
            List<String> postIds = new ArrayList<>();
            page.getRecords().forEach(v->{
                v.setCommentList(cyChannelCommentService.selectPostCommentList(v.getId()));
                v.setPriseList(cyChannelPostPriseService.selectPriseList(v.getId(),10l));
                postIds.add(String.valueOf(v.getId()));
                if(v.getUserId().equals(userId)){
                    v.setIsCreateUser(true);
                }else{
                    if(cyOrganization.getCreateUserId().equals(userId)){
                        v.setIsCreateUser(true);
                    }
                }
            });
            Map<Long,List<CyChannelPostFile>> fileMap = cyChannelPostFileService.selectPostFileList(postIds);
            if(MapUtils.isNotEmpty(fileMap)){
                page.getRecords().forEach(v->{
                    if(fileMap.containsKey(v.getId())){
                        v.setFileList(fileMap.get(v.getId()));
                    }
                });
            }
        }
        if(req.getPageNum()==1){
            AsyncUtil.runAsync(()->{
                cyChannelPostUserService.readUnReadPost(userId,req.getChannelId());
                /**
                 * 推送已读帖子的消息
                 */
                pushReadPostMsg(req.getChannelId(),userId,req.getOrganizationId());
            });
        }
        return page;
    }

    @Override
    public List<CyChannelTopic> selectTopicListForPost(Long channelId, Long userId){
        CyChannel cyChannel = cyChannelService.getById(channelId);
        CyChannelGroupUser channelGroupUser = cyChannelGroupUserService.getByChannelId(channelId,userId);
        if(!cyChannel.getCreateUserId().equals(userId)){
            if(channelGroupUser==null){
                return new ArrayList<>();
            }
            if(StringUtils.isEmpty(channelGroupUser.getGroupId())){
                return new ArrayList<>();
            }
        }
        QueryWrapper<CyChannelTopic> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("channel_id",channelId);
        if(channelGroupUser!=null && !cyChannel.getCreateUserId().equals(userId)){
            queryWrapper.like("group_ids",channelGroupUser.getGroupId());
        }
        queryWrapper.eq("del_flag",0).orderByAsc("sort_by");
        return cyChannelTopicService.list(queryWrapper);
    }


    @Override
    public PostInfoData getPostInfo(Long postId, Long userId){
        CyChannelPost post = cyChannelPostService.getById(postId);
        if(post==null){
            throw new CustomException("帖子不存在或者已被删除");
        }
        PostInfoData data = new PostInfoData();
        BeanUtils.copyProperties(post,data);
        CyUser cyUser = cyUserService.getById(post.getUserId());
        data.setAvatar(cyUser.getAvatar());
        data.setNickName(cyUser.getNickName());
        CyChannelTopic cyChannelTopic = cyChannelTopicService.getById(post.getTopicId());
        if(cyChannelTopic!=null){
            data.setTopicName(cyChannelTopic.getTopicName());
        }
        data.setCommentNum(cyChannelCommentService.getCommentNumByPostId(postId));
        data.setHasPrise(cyChannelPostPriseService.checkHasPrise(userId,String.valueOf(postId))?1:0);
        data.setPriseNum(cyChannelPostPriseService.getPriseNum(postId));
        data.setIsCreateUser(userId.equals(post.getUserId()));
        if(!data.getIsCreateUser()){
            data.setIsCreateUser(isCreateUser(post.getOrganizationId(),userId));
        }
        data.setPriseList(cyChannelPostPriseService.selectPriseList(postId,null));
        data.setFileList(cyChannelPostFileService.selectPostFileList(postId,null));
        return data;
    }

    @Override
    public IPage<PostCommentListData> selectCommentList(CommentReq req, Long userId){
        IPage<PostCommentListData> page = cyChannelCommentService.selectCommentList(new Page(req.getPageNum(),req.getPageSize())
                ,req.getPostId(),userId,1,null);
        if(CollectionUtils.isNotEmpty(page.getRecords())){

            page.getRecords().forEach(v->{
                IPage<PostCommentListData> replyPage = cyChannelCommentService.selectCommentList(new Page(1,1),req.getPostId()
                        ,userId,2,v.getId());
                if(replyPage.getTotal()>1){
                    v.setReplyNum(replyPage.getTotal());
                }
                v.setIsMine(v.getUserId().equals(userId));
                if(CollectionUtils.isNotEmpty(replyPage.getRecords())){
                    replyPage.getRecords().forEach(reply->{
                        reply.setIsMine(reply.getUserId().equals(userId));
                    });
                }
                v.setReplyList(replyPage.getRecords());
            });
        }
        return page;
    }

    @Override
    public IPage<PostCommentListData> selectSubCommentList(SubCommentReq req, Long userId){
        IPage<PostCommentListData> replyPage = cyChannelCommentService.selectCommentList(new Page(req.getPageNum(),req.getPageSize())
                ,req.getPostId(),userId,2,req.getCommentId());

        if(CollectionUtils.isNotEmpty(replyPage.getRecords())){
            replyPage.getRecords().forEach(reply->{
                reply.setIsMine(reply.getUserId().equals(userId));
            });
        }
        return replyPage;
    }

    @Override
    @Transactional
    public void pubPost(PubPostReq req, Long userId, Long organizationId){
        StringBuilder sb = new StringBuilder();
        if(CollectionUtils.isNotEmpty(req.getFileList())){
            req.getFileList().forEach(v->{
                if(v.getFileType()==1){
                    sb.append(v.getFileUrl()).append(",");
                }
            });
        }
        cyChannelRuleService.checkContentRule(req.getContent(),sb.toString(),req.getChannelId());
        CyChannelPost cyChannelPost;
        if(req.getId()!=null){
            cyChannelPost = cyChannelPostService.getById(req.getId());
            if(!cyChannelPost.getUserId().equals(userId)){
                throw new CustomException("无权限编辑");
            }
            cyChannelPost.setContent(req.getContent());
            cyChannelPost.setTopicId(req.getTopicId());
            cyChannelPostService.updateById(cyChannelPost);
            cyChannelPostFileService.remove(new QueryWrapper<CyChannelPostFile>().eq("post_id",req.getId()));
        }else{
            cyChannelPost = new CyChannelPost();
            cyChannelPost.setChannelId(req.getChannelId());
            cyChannelPost.setContent(req.getContent());
            cyChannelPost.setTopicId(req.getTopicId());
            cyChannelPost.setUserId(userId);
            cyChannelPost.setOrganizationId(organizationId);
            cyChannelPostService.save(cyChannelPost);

        }
        if(CollectionUtils.isNotEmpty(req.getFileList())){
            List<CyChannelPostFile> files = new ArrayList<>();
            for(int a=0;a<req.getFileList().size();a++){
                PostFileReq v = req.getFileList().get(a);
                CyChannelPostFile file = new CyChannelPostFile();
                file.setPostId(cyChannelPost.getId());
                file.setFileUrl(v.getFileUrl());
                file.setFileType(v.getFileType());
                file.setDuration(v.getDuration());
                file.setCoverImg(v.getCoverImg());
                file.setOrderBy(a);
                file.setCoverSize(v.getCoverSize());
                files.add(file);
            }
            cyChannelPostFileService.saveBatch(files);
        }

        AsyncUtil.runAsync(()->{
            CyChannelPostUser postUser = new CyChannelPostUser();
            postUser.setPostId(cyChannelPost.getId());
            postUser.setUserId(userId);
            cyChannelPostUserService.save(postUser);
            sendAllChannelMsg(cyChannelPost.getChannelId(),organizationId, MessageEnum.PUSH_CHANNEL_INFO);
        });


    }

    @Override
    @Transactional
    public void deletePost(Long postId,Long userId){
        CyChannelPost post = cyChannelPostService.getById(postId);
        if(!isCreateUser(post.getOrganizationId(),userId) && !post.getUserId().equals(userId)){
            throw new CustomException("无权限删除");
        }
        cyChannelPostService.removeById(postId);
        cyChannelCommentService.remove(new QueryWrapper<CyChannelComment>().eq("post_id",postId));
        cyChannelPostPriseService.remove(new QueryWrapper<CyChannelPostPrise>().eq("post_id",postId));
        cyChannelCommentPriseService.remove(new QueryWrapper<CyChannelCommentPrise>().eq("post_id",postId));
        cyChannelPostFileService.remove(new QueryWrapper<CyChannelPostFile>().eq("post_id",postId));
        AsyncUtil.runAsync(()->{
            sendAllChannelMsg(post.getChannelId(),post.getOrganizationId(),MessageEnum.PUSH_CHANNEL_INFO);
        });
    }

    @Override
    @Transactional
    public CommentData pubComment(PubCommentReq req, Long userId){
        CyChannelPost post = cyChannelPostService.getById(req.getPostId());
        if(post==null){
            throw new CustomException("帖子不存在或者已被删除");
        }
        if(StringUtils.isNotEmpty(req.getParentId())){
            CyChannelComment parent = cyChannelCommentService.getById(req.getParentId());
            if(parent==null){
                throw new CustomException("评论不存在或者已被删除");
            }
            if(parent.getUserId().equals(userId)){
                throw new CustomException("不能回复自己");
            }
        }
        CommentData data = new CommentData();
        cyChannelRuleService.checkContentRule(req.getComment(),req.getImageUrls(),post.getChannelId());
        CyChannelComment comment = new CyChannelComment();
        comment.setCommentType(req.getCommentType());
        comment.setComment(req.getComment());
        comment.setImagesUrl(req.getImageUrls());
        comment.setPostId(req.getPostId());
        comment.setUserId(userId);
        if(req.getCommentType()==2) {
            comment.setCureUserId(req.getCureUserId());
        }
        comment.setParentId(req.getParentId());

        cyChannelCommentService.save(comment);
        data.setId(comment.getId());
        data.setCommentTime(comment.getCreateTime());
        data.setIsMine(true);
        AsyncUtil.runAsync(()->{
            CyChannelMsg msg = new CyChannelMsg();
            msg.setChannelId(post.getChannelId());
            msg.setSendUserId(userId);
            if(req.getCommentType()==2){
                msg.setSendType(2);
                msg.setReceiveUserId(req.getCureUserId());
                msg.setReceiveType(3);
                msg.setReceiveItemId(req.getParentId());
                CyChannelComment parentComment = cyChannelCommentService.getById(req.getParentId());
                if(parentComment!=null){
                    msg.setSourceContent(parentComment.getComment());
                }else{
                    msg.setSourceContent("评论已删除");
                }
            }else{
                msg.setSendType(1);
                msg.setReceiveUserId(post.getUserId());
                msg.setReceiveType(2);
                msg.setReceiveItemId(String.valueOf(post.getId()));
                msg.setSourceContent(post.getContent());
            }
            msg.setSendItemId(comment.getId());
            msg.setMsgContent(req.getComment());
            msg.setReadFlag(0);
            msg.setOrganizationId(post.getOrganizationId());
            msg.setItemType(ChannelTypeEnum.TOPIC.getCode());
            msg.setItemId(String.valueOf(post.getId()));
            sendMsg(msg);
        });
        return data;
    }

    @Override
    public void priseComment(String commentId,Long userId){
        CyChannelComment comment = cyChannelCommentService.getById(commentId);
        if(comment==null){
            throw new CustomException("评论不存在或者已被删除");
        }
        boolean b = cyChannelCommentPriseService.checkHasPrise(userId,commentId);
        if(b){
            cyChannelCommentPriseService.remove(new QueryWrapper<CyChannelCommentPrise>().eq("comment_id",commentId).eq("user_id",userId));
        }else{
            CyChannelCommentPrise prise = new CyChannelCommentPrise();
            prise.setCommentId(commentId);
            prise.setUserId(userId);
            prise.setPriseTime(new Date());
            prise.setPostId(comment.getPostId());
            cyChannelCommentPriseService.save(prise);

            AsyncUtil.runAsync(()->{
                CyChannelPost post = cyChannelPostService.getById(comment.getPostId());
                CyChannelMsg msg = new CyChannelMsg();
                msg.setChannelId(post.getChannelId());
                msg.setSendUserId(userId);
                msg.setSendType(3);
                msg.setReceiveUserId(comment.getUserId());
                if(comment.getCommentType()==1){
                    msg.setReceiveType(2);
                }else{
                    msg.setReceiveType(3);
                }
                msg.setSendItemId(comment.getId());
                msg.setSourceContent(comment.getComment());
                msg.setReadFlag(0);
                msg.setOrganizationId(post.getOrganizationId());
                msg.setItemType(ChannelTypeEnum.TOPIC.getCode());
                msg.setItemId(String.valueOf(post.getId()));
                sendMsg(msg);
            });
        }
    }

    @Override
    public void prisePost(Long postId,Long userId){
        CyChannelPost post = cyChannelPostService.getById(postId);
        if(post==null){
            throw new CustomException("帖子不存在或者已被删除");
        }
        boolean b = cyChannelPostPriseService.checkHasPrise(userId,String.valueOf(postId));
        if(b){
            cyChannelPostPriseService.remove(new QueryWrapper<CyChannelPostPrise>().eq("post_id",postId).eq("user_id",userId));
        }else{
            CyChannelPostPrise prise = new CyChannelPostPrise();
            prise.setPostId(postId);
            prise.setUserId(userId);
            prise.setPriseTime(new Date());
            cyChannelPostPriseService.save(prise);
            AsyncUtil.runAsync(()->{
                CyChannelMsg msg = new CyChannelMsg();
                msg.setChannelId(post.getChannelId());
                msg.setSendUserId(userId);
                msg.setSendType(3);
                msg.setReceiveUserId(post.getUserId());
                msg.setReceiveType(1);
                msg.setSendItemId(String.valueOf(post.getId()));
                msg.setSourceContent(post.getContent());
                msg.setReadFlag(0);
                msg.setOrganizationId(post.getOrganizationId());
                msg.setItemType(ChannelTypeEnum.TOPIC.getCode());
                msg.setItemId(String.valueOf(post.getId()));
                sendMsg(msg);
            });
        }
    }

    @Override
    @Transactional
    public  void deleteComment(String commentId,Long organizationId,Long userId){
        CyChannelComment comment = cyChannelCommentService.getById(commentId);
        if(comment==null){
            throw new CustomException("评论不存在或者已被删除");
        }
        if(comment.getUserId().equals(userId) || isCreateUser(organizationId,userId)){
            cyChannelCommentService.removeById(commentId);
            cyChannelCommentPriseService.remove(new QueryWrapper<CyChannelCommentPrise>()
                    .eq("comment_id",commentId));
            cyChannelCommentService.remove(new QueryWrapper<CyChannelComment>().eq("parent_id",commentId));
        }else{
            throw new CustomException("无权限删除该评论");
        }
    }

    private boolean isCreateUser(Long organizationId,Long userId){
        CyOrganization organization = cyOrganizationService.getById(organizationId);
        return organization.getCreateUserId().equals(userId);
    }


}
